//
// Created by root on 19-7-29.
//

#include <unistd.h>
#include "hook_sys_attach.h"
#include "log_utils.h"
#include "dex_utils.h"
#include "AndHook.h"
#include "method_utils.h"
#include "jni_utils.h"
#include "class_utils.h"
#include "hook_gss.h"

#define TAG "ServiceManager-H"



static jobject ss_classloader= nullptr;

void hook_in_system_server(){
    if(!ss_classloader){
        LOGE("fail to get ss_classloader\n");
        return;
    }
    //com/android/server/am/ProcessList setOomAdj

}

static jmethodID old_finish_booting= nullptr;
void my_finish_booting(JNIEnv *env,jobject instance){
    if (!old_finish_booting) {
        LOGE("fail to get old_add_service\n");
        return;
    }
    LOGD("before sending BOOT_COMPLETED\n");
    //hook_get_sys_service(env);
    env->CallVoidMethod(instance,old_finish_booting);
}

static jmethodID old_add_service= nullptr;
//public static void addService(String name, IBinder service)
void my_add_service(JNIEnv *env,jclass def_class,
        jstring name,jobject service,bool reserved) {
    if (!old_add_service) {
        LOGE("fail to get old_add_service\n");
        return;
    }
    const char* c_name=env->GetStringUTFChars(name, nullptr);
    LOGD("before add service:%s\n",c_name);
    if(strcmp(c_name,"activity")==0){//AMS添加
        jclass ams_class=env->GetObjectClass(service);
        //public void setSystemProcess() -> final void finishBooting()
        ss_classloader=get_class_classloader(env,ams_class);

        LOGD("system_server app_classloader:%p\n",ss_classloader);
        jmethodID finish_booting=env->GetMethodID(ams_class,"finishBooting","()V");
        AKJavaHookMethodV(env,finish_booting, reinterpret_cast<void*>(my_finish_booting),&old_finish_booting);

        hook_in_system_server();
    }
    //调用原方法
    env->CallStaticVoidMethod(def_class,old_add_service,
            name,service,reserved);

    env->ReleaseStringUTFChars(name,c_name);
}

void hook_sm_add_service(JNIEnv *env) {
    jclass service_manager_class=env->FindClass("android/os/ServiceManager");
    //public static void addService(String name, IBinder service)
    jmethodID add_service=env->GetStaticMethodID(service_manager_class,"addService",
            "(Ljava/lang/String;Landroid/os/IBinder;Z)V");
    LOGD("addService jmethodID:%p\n",add_service);
    AKJavaHookMethodV(env,add_service,
            reinterpret_cast<void*>(my_add_service),&old_add_service);
    LOGD("old_add_service:%p\n",old_add_service);
}
